package com.ericsson.rm.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ericsson.rm.dao.repository.ProjectResourceDetailDaoRepository;
import com.ericsson.rm.service.ResourceSearchService;
import com.ericsson.rm.util.Utility;
import com.ericsson.rm.vo.ResourceAllocationChangeEventVO;
import com.ericsson.rm.vo.ResourceSearchInputVO;
import com.ericsson.rm.vo.ResourceSearchResponseVO;

@Service
public class ResourceSearchServiceImpl implements ResourceSearchService {
	
	private final static Logger logger = LoggerFactory.getLogger(ResourceSearchServiceImpl.class);
	private final static String CLASS_NAME = ResourceSearchServiceImpl.class.getSimpleName();
	
	@Autowired
	private ProjectResourceDetailDaoRepository projectResourceDetailDaoRepository;
	
	@Override
	public List<ResourceSearchResponseVO> searchResourceAllocation(ResourceSearchInputVO resourceSearchInput) {
		final String METHOD_NAME = CLASS_NAME + ".searchResourceAllocation() ";
		if(logger.isDebugEnabled()){
			logger.debug(METHOD_NAME+"entering...");
		}
		
		List<ResourceSearchResponseVO> resourceAllocationDetails = null;
		List<ResourceSearchResponseVO> resourceAllocationsAtFromDate = null;
		List<Object[]> resourceAllocationAtFromDateList = null;
		List<Object[]> resourceAllocationChangeEventList = null;
		String fromDate = resourceSearchInput.getFromDate();
		String toDate = resourceSearchInput.getToDate();
		List<String> resourceIdList = null;
		
		if(Utility.isNotEmpty(resourceSearchInput.getJobStage()) && Utility.isNotEmpty(resourceSearchInput.getSkillName())){
			//resourceAllocationAtFromDateList = projectResourceDetailDaoRepository.searchResourceAllocation(fromDate, resourceSearchInput.getJobStage(), resourceSearchInput.getSkillName());
		} else if (Utility.isNotEmpty(resourceSearchInput.getJobStage())){
			resourceAllocationAtFromDateList = projectResourceDetailDaoRepository.searchResourceAllocation(fromDate, resourceSearchInput.getJobStage());
		} else {
			resourceAllocationAtFromDateList = projectResourceDetailDaoRepository.searchResourceAllocation(fromDate);
		}
				
		if(Utility.isNotEmpty(resourceAllocationAtFromDateList)){
			resourceAllocationsAtFromDate = new ArrayList<ResourceSearchResponseVO>(resourceAllocationAtFromDateList.size());
			resourceIdList = new ArrayList<String>(resourceAllocationAtFromDateList.size());
			
			Iterator<Object[]> itr = resourceAllocationAtFromDateList.iterator();
			
			while(itr.hasNext()){
				Object[] resourceAllocation = itr.next();
				ResourceSearchResponseVO resourceSearchResponse = new ResourceSearchResponseVO();
				
				resourceSearchResponse.setResourceId(resourceAllocation[0].toString());
				resourceSearchResponse.setFirstName(resourceAllocation[1].toString());
				resourceSearchResponse.setLastName(resourceAllocation[2].toString());
				resourceSearchResponse.setSignum(resourceAllocation[3].toString());
				resourceSearchResponse.setLineManagerSignum(resourceAllocation[4].toString());
				resourceSearchResponse.setJobStage(resourceAllocation[5].toString());
				resourceSearchResponse.setRoleName(resourceAllocation[6].toString());
				resourceSearchResponse.setTotalAllocationPercentage(Integer.valueOf(resourceAllocation[7].toString()));
				resourceSearchResponse.setFromDate(fromDate);
				resourceSearchResponse.setToDate(toDate);
				
				resourceAllocationsAtFromDate.add(resourceSearchResponse);
				resourceIdList.add(resourceSearchResponse.getResourceId());
			}
		}
		
		if(logger.isDebugEnabled()){
			logger.debug(METHOD_NAME+"ResourceAllocationsAtFromDate : " + Utility.displayCollectionBean(resourceAllocationsAtFromDate));
		}
		System.out.println(METHOD_NAME+"ResourceAllocationsAtFromDate : " + Utility.displayCollectionBean(resourceAllocationsAtFromDate));
		
		if(Utility.isNotEmpty(resourceAllocationsAtFromDate)){
			resourceAllocationChangeEventList = projectResourceDetailDaoRepository.getResourceAllocationChangeEvents(fromDate, toDate, resourceIdList);
			
			if(Utility.isNotEmpty(resourceAllocationChangeEventList)){
				List<ResourceAllocationChangeEventVO> allocationChangeEvents = new ArrayList<ResourceAllocationChangeEventVO>(resourceAllocationChangeEventList.size());
				Iterator<Object[]> itr = resourceAllocationChangeEventList.iterator();
				
				while(itr.hasNext()){
					Object[] allocationChangeEventData = itr.next();
					ResourceAllocationChangeEventVO allocationChangeEvent = new ResourceAllocationChangeEventVO();
					
					allocationChangeEvent.setResourceId(allocationChangeEventData[0].toString());
					allocationChangeEvent.setEventDate(Utility.convertStringToDate(allocationChangeEventData[1].toString(), "yyyy-MM-dd"));
					allocationChangeEvent.setEventType(allocationChangeEventData[2].toString());
					allocationChangeEvent.setAllocationChange(Integer.valueOf(allocationChangeEventData[3].toString()));
					
					allocationChangeEvents.add(allocationChangeEvent);
				}
				
				if(logger.isDebugEnabled()){
					logger.debug(METHOD_NAME+"ResourceAllocationChangeEvents : " + Utility.displayCollectionBean(allocationChangeEvents));
				}
				System.out.println("ResourceAllocationChangeEvents : " + Utility.displayCollectionBean(allocationChangeEvents));
				
				if(Utility.isNotEmpty(allocationChangeEvents)){
					Map<String, List<ResourceAllocationChangeEventVO>> resourceAllocationChangeEventMap = this.populateResourceAllocationChnageEventMap(allocationChangeEvents);
					
					if(logger.isDebugEnabled()){
						logger.debug(METHOD_NAME+"ResourceAllocationChnageEventMap : " + resourceAllocationChangeEventMap);
					}
					System.out.println(METHOD_NAME+"ResourceAllocationChnageEventMap : " + resourceAllocationChangeEventMap);
					
					resourceAllocationDetails = new ArrayList<ResourceSearchResponseVO>();
					Iterator<ResourceSearchResponseVO> itr1 = resourceAllocationsAtFromDate.iterator();
					
					while(itr1.hasNext()){
						ResourceSearchResponseVO resourceAllocationAtFromDate = itr1.next();
						ResourceSearchResponseVO resourceSearchResponse = (ResourceSearchResponseVO) Utility.copyBean(resourceAllocationAtFromDate, ResourceSearchResponseVO.class);
						resourceAllocationDetails.add(resourceSearchResponse);
												
						String resourceId = resourceSearchResponse.getResourceId();
						List<ResourceAllocationChangeEventVO> allocationChangeEventSubList = resourceAllocationChangeEventMap.get(resourceId);
						
						if(Utility.isNotEmpty(allocationChangeEventSubList)){
							ResourceSearchResponseVO nextResourceSearchResponse = null;
							ResourceSearchResponseVO prevResourceSearchResponse = resourceSearchResponse;
							Iterator<ResourceAllocationChangeEventVO> itr2 = allocationChangeEventSubList.iterator();
							Date eventDate = null;
							Integer allocationChange = null;
							Integer currentTotalAllocation = resourceSearchResponse.getTotalAllocationPercentage();
							
							while(itr2.hasNext()){
								ResourceAllocationChangeEventVO resourceAllocationChangeEvent = itr2.next();
								eventDate = resourceAllocationChangeEvent.getEventDate();
								allocationChange = resourceAllocationChangeEvent.getAllocationChange();
								currentTotalAllocation = currentTotalAllocation + allocationChange;
								prevResourceSearchResponse.setToDate(Utility.convertDateToString(eventDate));
								
								nextResourceSearchResponse = (ResourceSearchResponseVO) Utility.copyBean(prevResourceSearchResponse, ResourceSearchResponseVO.class);
								nextResourceSearchResponse.setFromDate(Utility.convertDateToString(eventDate));
								nextResourceSearchResponse.setTotalAllocationPercentage(currentTotalAllocation);
								
								resourceAllocationDetails.add(nextResourceSearchResponse);
								prevResourceSearchResponse = nextResourceSearchResponse;
							}
							//For last event of the resource
							prevResourceSearchResponse.setToDate(toDate);
						}
									
						if(logger.isDebugEnabled()){
							logger.debug(METHOD_NAME+"Final Response: ResourceAllocationDetails : " + Utility.displayCollectionBean(resourceAllocationDetails));
						}
						System.out.println(METHOD_NAME+"Final Response: ResourceAllocationDetails : " + Utility.displayCollectionBean(resourceAllocationDetails));
					}
				}
			}
			
		}
		
		
		return resourceAllocationDetails;
	}

	private Map<String, List<ResourceAllocationChangeEventVO>> populateResourceAllocationChnageEventMap(List<ResourceAllocationChangeEventVO> allocationChangeEvents) {
		
		Map<String, List<ResourceAllocationChangeEventVO>> resourceAllocationChangeEventMap = new TreeMap<String, List<ResourceAllocationChangeEventVO>>();
		List<ResourceAllocationChangeEventVO> allocationChangeEventSubList = null;
		ResourceAllocationChangeEventVO allocationChangeEvent = null;
		String resourceId = null;
		Iterator<ResourceAllocationChangeEventVO> itr = allocationChangeEvents.iterator();
		
		while(itr.hasNext()){
			allocationChangeEvent = itr.next(); 
			resourceId = allocationChangeEvent.getResourceId();
			
			if(resourceAllocationChangeEventMap.containsKey(resourceId)){
				allocationChangeEventSubList = resourceAllocationChangeEventMap.get(resourceId);
				allocationChangeEventSubList.add(allocationChangeEvent);
			} else {
				allocationChangeEventSubList = new ArrayList<ResourceAllocationChangeEventVO>();
				allocationChangeEventSubList.add(allocationChangeEvent);
				resourceAllocationChangeEventMap.put(resourceId, allocationChangeEventSubList);
			}
		}
		
		return resourceAllocationChangeEventMap;
	}
	
	
}
